namespace PengYouClient
{
	using System;
	using Extensibility;
	using System.Runtime.InteropServices;
    using System.Reflection;
    using Microsoft.Office.Core;
    using System.IO;
    using System.Windows.Forms;

	#region Read me for Add-in installation and setup information.
	// When run, the Add-in wizard prepared the registry for the Add-in.
	// At a later time, if the Add-in becomes unavailable for reasons such as:
	//   1) You moved this project to a computer other than which is was originally created on.
	//   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
	//   3) Registry corruption.
	// you will need to re-register the Add-in by building the PengYouClientSetup project, 
	// right click the project in the Solution Explorer, then choose install.
	#endregion
	
	/// <summary>
	///   The object for implementing an Add-in.
	/// </summary>
	/// <seealso class='IDTExtensibility2' />
	[GuidAttribute("0CEBEDF8-C8E8-4C34-B31C-567E24EFCCF8"), ProgId("PengYouClient.Connect")]
	public class Connect : Object, Extensibility.IDTExtensibility2
	{
		/// <summary>
		///		Implements the constructor for the Add-in object.
		///		Place your initialization code within this method.
		/// </summary>
        /// 
        CommandBars oCommandBars;
        CommandBar oStandardBar;

        private CommandBarButton Open;
        private CommandBarButton Publish;
        private CommandBarButton PublishAs;
        private CommandBarButton OpenVersion;
        //private CommandBarButton EditKewords;
        //private CommandBarButton EditDescription;
        private CommandBarButton EditRights;
        private CommandBarButton Export;
        private CommandBarButton Parameters;
        private CommandBarButton Help;
        private CommandBarButton About;
        private CommandBarPopup PengYouMenu;
        public Word._Application app;

        string filename;
        string realname;
        string docbasedir;
        string parentname;
        public bool compareversion;

        bool configFile;

        public string ParentName
        {
            set
            {
                parentname = value;
            }
        }

        public string Docbasedir
        {
            set
            {
                docbasedir = value;
            }
        }

        public string Filename
        {
            set
            {
                filename = value;
            }
        }

        public string RealFilename
        {
            set
            {
                realname = value;
            }
        }

		public Connect()
		{
		}

        /// <summary>
        /// First call from Microsoft Word add-in anchor system
        /// </summary>
        /// <param name="application">Representing Word application</param>
        /// <param name="connectMode">The way Word connect the add-in (ie: see enum)</param>
        /// <param name="addInInst">Representing the add-in object</param>
        /// <param name="custom"></param>
        public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
        {
            applicationObject = application;
            addInInstance = addInInst;

            if (connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
            {
                OnStartupComplete(ref custom);
            }

        }

        /// <summary>
        /// Last call from Word to the add-in, when the user close Word
        /// </summary>
        /// <param name="disconnectMode"></param>
        /// <param name="custom"></param>
        public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
        {
            if (disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
            {
                OnBeginShutdown(ref custom);
            }
            applicationObject = null;
        }


        public void OnAddInsUpdate(ref System.Array custom)
        {
        }

        /// <summary>
        /// Called after a OnConnection when the add-in is connected to Word
        /// Creation of the PengYou menu
        /// </summary>
        /// <param name="custom"></param>
        public void OnStartupComplete(ref System.Array custom)
        {
            object omissing = System.Reflection.Missing.Value;
            configFile = SettingsManager.readXML();
            LanguageManager.SetResource("PengYouClient.ress");
            if (SettingsManager.language != "en-EN" && SettingsManager.language != null)
                LanguageManager.SetLanguage(SettingsManager.language);
            app = (Word._Application)applicationObject;            

            try
            {
                oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty, null, applicationObject, null);
            }
            catch (Exception)
            {
                // Outlook has the CommandBars collection on the Explorer object.
                object oActiveExplorer;
                oActiveExplorer = applicationObject.GetType().InvokeMember("ActiveExplorer", BindingFlags.GetProperty, null, applicationObject, null);
                oCommandBars = (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty, null, oActiveExplorer, null);
            }

            // Set up a custom button on the "Standard" commandbar.
            try
            {
                oStandardBar = oCommandBars["Menu Bar"];
            }
            catch (Exception)
            {
                // Access names its main toolbar Database.
                oStandardBar = oCommandBars["Database"];
            }

            // In case the button was not deleted, use the exiting one.
            PengYouMenu = null;
            PengYouMenu = (CommandBarPopup)oStandardBar.FindControl(MsoControlType.msoControlPopup, omissing, LanguageManager.GetString("WordMenuTag"), true, true);
            if (PengYouMenu != null)
                PengYouMenu.Delete(false);
            PengYouMenu = (CommandBarPopup)oStandardBar.Controls.Add(MsoControlType.msoControlPopup, omissing, omissing, omissing, true);
            PengYouMenu.Caption = LanguageManager.GetString("WordMenu");
            PengYouMenu.Tag = LanguageManager.GetString("WordMenuTag");

            Open = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            Open.Caption = LanguageManager.GetString("WordMenuOpen");
            Open.Tag = Open.Caption;

            Publish = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            Publish.Caption = LanguageManager.GetString("WordMenuPublish");
            Publish.Tag = Publish.Caption;

            PublishAs = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            PublishAs.Caption = LanguageManager.GetString("WordMenuPublishAs");
            PublishAs.Tag = PublishAs.Caption;

            OpenVersion = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            OpenVersion.Caption = LanguageManager.GetString("WordMenuOpenVersion");
            OpenVersion.Tag = OpenVersion.Caption;
            OpenVersion.BeginGroup = true;

            EditRights = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            EditRights.Caption = LanguageManager.GetString("WordMenuEditRights");
            EditRights.Tag = EditRights.Caption;

            Export = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            Export.Caption = LanguageManager.GetString("WordMenuExport");
            Export.Tag = Export.Caption;

            Parameters = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            Parameters.Caption = LanguageManager.GetString("WordMenuParameters");
            Parameters.Tag = Parameters.Caption;
            Parameters.BeginGroup = true;

            Help = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            Help.Caption = LanguageManager.GetString("WordMenuHelp");
            Help.Tag = Help.Caption;

            About = (CommandBarButton)PengYouMenu.Controls.Add(1, omissing, omissing, omissing, true);
            About.Caption = LanguageManager.GetString("WordMenuAbout");
            About.Tag = About.Caption;            

            Publish.Visible = true;
            Publish.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.Publish_Click);

            PublishAs.Visible = true;
            PublishAs.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.PublishAs_Click);

            Open.Visible = true;
            Open.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.Open_Click);

            OpenVersion.Visible = true;
            OpenVersion.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.OpenVersion_Click);

            EditRights.Visible = true;

            Export.Visible = true;

            Parameters.Visible = true;
            Parameters.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.Parameters_Click);

            Help.Visible = true;
            Help.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.Help_Click);

            About.Visible = true;
            About.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.About_Click);

            object oName = applicationObject.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, applicationObject, null);         

            string prop;
            if (!pengyouUtils.GetWordDocumentProp(app, "PengYou", out prop))
            {
                Publish.Enabled = false;
                OpenVersion.Enabled = false;
                EditRights.Enabled = false;
                Export.Enabled = false;
            }

            Word.ApplicationEvents4_Event appEvents = (Word.ApplicationEvents4_Event)app;
            appEvents.DocumentOpen += new Word.ApplicationEvents4_DocumentOpenEventHandler(appEvents_DocumentOpen);
        }

        /// <summary>
        /// Event catch when the user open a Word document
        /// Used to unhide some elements of the PengYou menu
        /// </summary>
        /// <param name="Doc"></param>
        public void appEvents_DocumentOpen(Word._Document Doc)
        {
            makePengYouMenuAppear();
        }

        /// <summary>
        /// Enable or disable some items of the PengYou menu depending if the document
        /// is or not a PengYou document
        /// </summary>
        private void makePengYouMenuAppear()
        {
            string prop;
            if (!pengyouUtils.GetWordDocumentProp(app, "PengYou", out prop))
            {
                Publish.Enabled = false;
                OpenVersion.Enabled = false;
                EditRights.Enabled = false;
                Export.Enabled = false;
            }
            else
            {
                Publish.Enabled = true;
                OpenVersion.Enabled = true;
                EditRights.Enabled = false;
                Export.Enabled = false;
            }
        }

        /// <summary>
        /// Before on disconnection
        /// We make the PengYou menu disapear
        /// </summary>
        /// <param name="custom"></param>
        public void OnBeginShutdown(ref System.Array custom)
        {
            object omissing = System.Reflection.Missing.Value;

            Open.Delete(omissing);
            Open = null;

            Publish.Delete(omissing);
            Publish = null;

            PublishAs.Delete(omissing);
            PublishAs = null;

            OpenVersion.Delete(omissing);
            OpenVersion = null;

            EditRights.Delete(omissing);
            EditRights = null;

            Export.Delete(omissing);
            Export = null;

            Parameters.Delete(omissing);
            Parameters = null;

            Help.Delete(omissing);
            Help = null;

            About.Delete(omissing);
            About = null;

            PengYouMenu = null;
        }

        /// <summary>
        /// Update a custom propertie of the document
        /// </summary>
        /// <param name="propName">Propertie to set</param>
        /// <param name="propValue">Value of the property</param>
        /// <param name="doc">Reference to the Word document</param>
        /// <returns></returns>
        private bool UpdateCustomDocumentPropertie(string propName, string propValue, Word.Document doc)
        {
            try
            {
                object docProps = doc.CustomDocumentProperties;
                Type docPropsType = docProps.GetType();
                object Prop = docPropsType.InvokeMember("Item",
                    BindingFlags.Default |
                    BindingFlags.GetProperty,
                    null, docProps,
                    new object[] { propName });
                Type PropType = Prop.GetType();
                PropType.InvokeMember("Item",
                    BindingFlags.Default |
                    BindingFlags.SetProperty,
                    null, docProps,
                    new object[] { propName, propValue });
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Set a custom propertie of the document
        /// </summary>
        /// <param name="strIndex">Name of the propertie to set</param>
        /// <param name="strValue">Value of the property to set</param>
        /// <param name="doc">Reference to the Word document</param>
        /// <returns></returns>
        private bool SetCustomDocumentPropertie(string strIndex, string strValue, Word.Document doc)
        {
            DocumentProperties prop;
            object omissing = System.Reflection.Missing.Value;

            try
            {
                prop = (DocumentProperties)doc.CustomDocumentProperties;
                prop.Add(strIndex, false, Microsoft.Office.Core
                    .MsoDocProperties.msoPropertyTypeString, strValue, omissing);
                return true;
            }
            catch (Exception)
            {
                if (!UpdateCustomDocumentPropertie(strIndex, strValue, doc))
                    return false;
                else
                    return true;
            }
        }

        /// <summary>
        /// Set properties so the document became a PengYou document
        /// </summary>
        /// <param name="doc">Reference to the Word document</param>
        private void SetWordDocumentProperties(Word.Document doc)
        {
            bool success = true;

            if (this.parentname != null)
                this.realname = this.parentname;
            if (!SetCustomDocumentPropertie("PengYou", "Oui", doc))
                success = false;
            if (!SetCustomDocumentPropertie("PengYouBaseDir", this.docbasedir, doc))
                success = false;
            if (!SetCustomDocumentPropertie("PengYouDocName", this.realname, doc))
                success = false;
            if (success == false)
                System.Windows.Forms.MessageBox.Show("Unable to set document custom properties");
        }

        /// <summary>
        /// Download the version selected and compare it with the actual document
        /// </summary>
        private void CompareVersion()
        {
            string pengyoupath = SettingsManager.PengYouPath + "repository\\";
            try
            {
                File.Delete(pengyoupath + docbasedir + realname);
                if (docbasedir.Length != 0)
                    Directory.CreateDirectory(pengyoupath + docbasedir);
                File.Copy(this.filename, pengyoupath + docbasedir + realname);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            string file = pengyoupath + docbasedir + realname;
            object omissing = Missing.Value;
            object target = Word.WdCompareTarget.wdCompareTargetNew;
            app.ActiveDocument.Compare(file, ref omissing, ref target, ref omissing, ref omissing,
                ref omissing, ref omissing, ref omissing);
        }

        /// <summary>
        /// Download and open the document previously selected
        /// </summary>
        private void OpenWordDocument()
        {
            string pengyoupath = SettingsManager.PengYouPath + "repository\\";
            if (!docbasedir.EndsWith("/"))
                docbasedir += "/";
            try
            {
                if (docbasedir.Length != 0)
                    Directory.CreateDirectory(pengyoupath + docbasedir);
                File.Delete(pengyoupath + docbasedir + realname);
                File.Copy(this.filename, pengyoupath + docbasedir + realname);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            object file = pengyoupath + docbasedir + realname;

            object omissing = Missing.Value;
            Word.Document doc = app.Documents.Open(ref file, ref omissing, ref omissing, ref omissing, ref omissing,
 ref omissing, ref omissing, ref omissing, ref omissing, ref omissing, ref omissing,
 ref omissing, ref omissing, ref omissing, ref omissing, ref omissing);            
            SetWordDocumentProperties(doc);
            doc.Saved = false;
            doc.Save();
            doc.Activate();

            Publish.Enabled = true;
            OpenVersion.Enabled = true;
            EditRights.Enabled = false;
            Export.Enabled = false;
        }

        /// <summary>
        /// Click on the Open menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void Open_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            filename = null;
            Open DialogOpen = new Open(app, this);
            DialogOpen.ShowDialog();
            if (filename.Length != 0)
                OpenWordDocument();
        }

        /// <summary>
        /// Click on the Publish menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void Publish_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            Publish DialogPublish = new Publish(app);
            DialogPublish.ShowDialog();
        }

        /// <summary>
        /// Click on the PublishAs menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void PublishAs_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            PublishAs DialogPublishAs = new PublishAs(app, this);
            DialogPublishAs.ShowDialog();
            makePengYouMenuAppear();
        }

        /// <summary>
        /// Click on the About menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void About_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            About DialogAbout = new About();
            DialogAbout.ShowDialog();
        }

        /// <summary>
        /// Click on the parameters menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void Parameters_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            Settings DialogParameters = new Settings();
            DialogParameters.ShowDialog();
        }

        /// <summary>
        /// Click on the Open at a previous date menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void OpenVersion_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {
            compareversion = false;
            parentname = null;
            OpenVersion DialogOpenVersion = new OpenVersion(app, this);
            DialogOpenVersion.ShowDialog();
            if (compareversion == true)
                CompareVersion();
            else if (filename.Length != 0)
                OpenWordDocument();
        }

        /// <summary>
        /// Click on the Help menu
        /// </summary>
        /// <param name="cmdBarbutton"></param>
        /// <param name="cancel"></param>
        private void Help_Click(CommandBarButton cmdBarbutton, ref bool cancel)
        {            
            System.Windows.Forms.Help.ShowHelp(cmdBarbutton.Control as Control, SettingsManager.PengYouPath + "PengYou.chm");
        }

		private object applicationObject;
		private object addInInstance;
	}
}